package viewModel;

import java.util.ArrayList;
import java.util.List;

import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.CategoryModel;
import org.zkoss.zul.Chart;
import org.zkoss.zul.Div;
import org.zkoss.zul.PieModel;
import org.zkoss.zul.SimpleCategoryModel;
import org.zkoss.zul.SimplePieModel;

import Misc.Variables;
import databaseHelper.ExamDAO;
import databaseHelper.WorkedExamDAO;
/**
 * Composer proving the different charts for the exam statistic section
 * @author Rupert
 *
 */
public class workedExamsChartComposer extends SelectorComposer<Div>{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	

	int numberOfExercies = getNumberOfExercises();
	
	WorkedExamDAO workedExams = new WorkedExamDAO();
	
	@Wire
	Chart pieChart;
	
	@Wire
	Chart secondPieChart;
	
	@Wire
	Chart averagePointsBarChart;
	
	@Wire
	Chart secondAveragePointsBarChart;
	
	@Wire
	Chart pointsDistributionChart;
	
	@Wire
	Chart secondPointsDistributionChart;

	@Override
    public void doAfterCompose(Div comp) throws Exception {
        super.doAfterCompose(comp);
 
		PieModel piemodel = new SimplePieModel();
		double[] possibleGrades = {1.0,1.3,1.7,2.0,2.3,2.7,3.0,3.3,3.7,4.0, 4.3, 4.7, 5.0};
		for(int i=0; i<possibleGrades.length; i++){

			Object tmpObject =Sessions.getCurrent().getAttribute(Variables.workedExamSessionAttribut);
			if(tmpObject == null){
				Executions.sendRedirect("login.zul");
				return;
			}
			int subjectId = new Integer(tmpObject.toString());
			
			int currCount =	workedExams.getNumberOfGrades(possibleGrades[i], subjectId);
			if(currCount!=0){
				piemodel.setValue(possibleGrades[i],currCount);
			}
		}
		
        pieChart.setModel(piemodel);
        
		 
        
        
        PieModel secondPiemodel = new SimplePieModel();
		for(int i=0; i<possibleGrades.length; i++){

			Object tmpObject =Sessions.getCurrent().getAttribute(Variables.workedExamSessionAttribut);
			if(tmpObject == null){
				Executions.sendRedirect("login.zul");
				return;
			}
			int subjectId = new Integer(tmpObject.toString());
			
			int currCount =	workedExams.getNumberOfGradesSecond(possibleGrades[i], subjectId);
			if(currCount!=0){
				secondPiemodel.setValue(possibleGrades[i],currCount);
			}
		}
         
        secondPieChart.setModel(secondPiemodel);
        
        /**
         * Finished first chart row - the pie chart
         */
       
        /**
         * Composing second chart row- the averagePoints chart
         */
        
        double[] workedExamAverage = getAveragePoints();
		if(workedExamAverage.length<numberOfExercies){

		}
		
		
		double[] maxPointsPerExercise = getMaxPoints();
		
        CategoryModel catmodel = new SimpleCategoryModel();
		if(workedExamAverage != null){
	        for(int i=0; i<numberOfExercies; i++){
	        	catmodel.setValue("Durchschnitt", "A" + (i+1), workedExamAverage[i]);
	        	catmodel.setValue("Maximum", "A" + (i+1), maxPointsPerExercise[i]);
	        }
		}

		averagePointsBarChart.setModel(catmodel);
		
		
		double[] workedExamAverageSecond = getAveragePointsSecond();
		if(workedExamAverage.length<numberOfExercies){

		}
		
		
		
        CategoryModel catmodelSecond = new SimpleCategoryModel();
		if(workedExamAverage != null){
	        for(int i=0; i<numberOfExercies; i++){
	        	catmodelSecond.setValue("Durchschnitt", "A" + (i+1), workedExamAverageSecond[i]);
	        	catmodelSecond.setValue("Maximum", "A" + (i+1), maxPointsPerExercise[i]);
	        }
		}

		secondAveragePointsBarChart.setModel(catmodelSecond);

        /**
         * Finished second chart - the averagePoints chart
         */
		

        /**
         * Composing third chart - the achievedPoints chart
         */
		
		double maxPointsTotal = 0;
		
		for(int i=0; i< maxPointsPerExercise.length; i++){
			maxPointsTotal = maxPointsTotal + maxPointsPerExercise[i];
		}
		
		
		
		List<Double> listOfachievedPoints = getAchievedPointsInList();
		
		int[] pointsOccurence = new int[(int) (2 * maxPointsTotal)];
		
		for(int i=0; i<listOfachievedPoints.size(); i++){
			pointsOccurence[(int)(listOfachievedPoints.get(i)*2)]++;
		}

		System.out.println("Max Points: "+maxPointsTotal);
		
		
        CategoryModel catmodel_pointDistribution = new SimpleCategoryModel();
	    for(int i=0; i<pointsOccurence.length; i++){
	    	catmodel_pointDistribution.setValue("Achieved points", (i/(double)2), pointsOccurence[i]);
	     }
	    
	    pointsDistributionChart.setModel(catmodel_pointDistribution);
	    
	    /*
	     * first correction done
	     */
	    List<Double> listOfachievedPointsSecond = getAchievedPointsInListSecond();
		
		int[] pointsOccurenceSecond = new int[(int) (2 * maxPointsTotal)];
		
		for(int i=0; i<listOfachievedPointsSecond.size(); i++){
			pointsOccurenceSecond[(int)(listOfachievedPointsSecond.get(i)*2)]++;
		}

		System.out.println("Max Points: "+maxPointsTotal);
		
		
        CategoryModel catmodel_pointDistribution_second = new SimpleCategoryModel();
	    for(int i=0; i<pointsOccurenceSecond.length; i++){
	    	catmodel_pointDistribution_second.setValue("Achieved points", (i/(double)2), pointsOccurenceSecond[i]);
	     }
	    
	    secondPointsDistributionChart.setModel(catmodel_pointDistribution_second);
	    
	    
	    
	    
        /**
         * Finished third chart row - the achievedPoints chart
         */
        
    }
	
	/**
	 * calculates the average points on the exercises
	 * @return double[] containing the averages
	 */
	public double[] getAveragePoints(){
		
		Object tmpObject =Sessions.getCurrent().getAttribute(Variables.workedExamSessionAttribut);
		if(tmpObject == null)
			return new double[1];
		int examId = new Integer(tmpObject.toString());
		if(examId>0){
			double[] returnArray = workedExams.getAveragePoints(examId);
			if(returnArray==null){
				return new double[numberOfExercies];
			}else{
				return returnArray;
			}
		}else{
			return new double[1];
		}
	}
	
	/**
	 * calculates the average points on the exercises
	 * @return double[] containing the averages
	 */
	public double[] getAveragePointsSecond(){
		
		Object tmpObject =Sessions.getCurrent().getAttribute(Variables.workedExamSessionAttribut);
		if(tmpObject == null)
			return new double[1];
		int examId = new Integer(tmpObject.toString());
		if(examId>0){
			double[] returnArray = workedExams.getAveragePointsSecond(examId);
			if(returnArray==null){
				return new double[numberOfExercies];
			}else{
				return returnArray;
			}
		}else{
			return new double[1];
		}
	}
	

	/**
	 * Method returning the number of exercises in the currentExam
	 * @return
	 */
	public int getNumberOfExercises(){
		ExamDAO exams = new ExamDAO();
		Object tmpObject = Sessions.getCurrent().getAttribute(Variables.workedExamSessionAttribut);
		
		if(tmpObject == null)
			return 0;
		
		int examId = new Integer(tmpObject.toString());
		return exams.getNumberOfExercises(examId);
	}
	
	/**
	 * returning an array with the maxPoints for each exercise
	 * @return
	 */
	public double[] getMaxPoints(){
		ExamDAO exams = new ExamDAO();
		Object tmpObject = Sessions.getCurrent().getAttribute(Variables.workedExamSessionAttribut);
		
		if(tmpObject == null)
			return new double[1];
		
		int examId = new Integer(tmpObject.toString());
		return exams.getMaxPointsArray(examId);
		
	}
	
	/**
	 * returning a list with all points result of the worked exams
	 * @return
	 */
	private List<Double> getAchievedPointsInList(){
		Object tmpObject = Sessions.getCurrent().getAttribute(Variables.workedExamSessionAttribut);
		
		if(tmpObject == null)
			return new ArrayList<Double>();
		
		int examId = new Integer(tmpObject.toString());
		return workedExams.getAchievedPointsList(examId);
	}
	
	/**
	 * returning a list with all points result of the worked exams
	 * @return
	 */
	private List<Double> getAchievedPointsInListSecond(){
		Object tmpObject = Sessions.getCurrent().getAttribute(Variables.workedExamSessionAttribut);
		
		if(tmpObject == null)
			return new ArrayList<Double>();
		
		int examId = new Integer(tmpObject.toString());
		return workedExams.getAchievedPointsListSecond(examId);
	}

	
}
